package com.gjintel.business.proj.service.impl;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.apache.commons.lang.ObjectUtils.Null;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.gjintel.business.proj.dao.IProjectInfoDao;
import com.gjintel.business.proj.model.ProjectBidInfo;
import com.gjintel.business.proj.model.ProjectInfo;
import com.gjintel.business.proj.model.ProjectMaxCount;
import com.gjintel.business.proj.service.IProjectInfoService;
import com.gjintel.framework.cache.InitCacheData;
import com.gjintel.framework.cache.InitCacheData.CacheType;
import com.gjintel.framework.constant.ProjectStatus;
import com.gjintel.framework.dept.model.Dept;
import com.gjintel.framework.log.model.LogInfo;
import com.gjintel.framework.log.util.LogUtil;
import com.gjintel.framework.log.util.LogUtil.LogType;
import com.gjintel.framework.projecttype.model.ProjectType;
import com.gjintel.framework.res.model.Resources;
import com.gjintel.framework.user.model.User;
import com.gjintel.framework.util.FileResUtil;
import com.gjintel.framework.validateunique.dao.IValidateUniqueDao;
import com.gjintel.sdk.base.dao.Page;
import com.gjintel.sdk.base.dao.Sort;
import com.gjintel.sdk.base.service.impl.BaseServiceImpl;
import com.gjintel.sdk.util.StringUtil;
import com.gjintel.workflow.trade.service.IWorkflowProcessInstanceService;

@Service
@SuppressWarnings("unchecked")
public class ProjectInfoServiceImpl extends BaseServiceImpl implements IProjectInfoService{

	@Resource
	private IProjectInfoDao projectInfoDaoImpl;
	
	
	@Autowired
	private IWorkflowProcessInstanceService workflowProcessInstanceService;
	
	@Autowired
	protected IValidateUniqueDao validateUniqueDao;
	
	/**
	 *评标流程key
	 */
	private static final String PROCESS_DEFINATION_KEY = "tender";
	
	/**
	 * 不评标流程key
	 */
	private static final String PROCESS_NOBID_KEY="tender_nobid";
	
	/**
     * 项目的提交和保存操作
     */
	@Override
	public void saveProject(User user,String budgetMenuData,ProjectInfo project,int commitType) {
		//项目类型名称保存
		if (StringUtil.isEmpty(project.getId())) {// 新增
			project.setAgentName(user.getLoginName());//委托人
			project.setCreateId(user.getId());//委托人id
			project.setCreateTime(new Date());
			ProjectType catagory = this.get(ProjectType.class, project.getCatagoryId());
			if(catagory!=null){
				project.setCatagoryName(this.get(ProjectType.class, project.getCatagoryId()).getName());//项目类型
			}
			//project.setTradeType("J");//交易方式DictUtil.dict("tradeType", "J").getName()
			//project.setAuditable(true);//是否评标
			this.save(project);
			
			//启动流程
			//判断是否评标
			String processDefinitionKey = PROCESS_DEFINATION_KEY;//评标流程
			if(!project.getAuditable()){
				processDefinitionKey=PROCESS_NOBID_KEY;//不评标流程
			}else{
				project.setManageName("");//将项目负责人名称置为空
			}
			Map<String, Object> variables=new HashMap<String, Object>();
			variables.put("applyUserId", user.getId());
			ProcessInstance processIntance = workflowProcessInstanceService.startProcessInstance(processDefinitionKey, project.getId(), variables);
			project.setWorkflowId(processIntance.getId());
			project.setWorkflowKey(processDefinitionKey);
			
			//状态设置
			if(project.getAuditable()){//评标流程
				if(Integer.valueOf(ProjectStatus.WAIT_SUBMIT.toString())==commitType){//保存操作
					project.setStatus(Integer.valueOf(ProjectStatus.WAIT_SUBMIT.toString()));//待提交
				}else{//提交
					project.setStatus(Integer.valueOf(ProjectStatus.WAIT_AUDIT.toString()));//待审核
					
					//流程 完成任务
					Task task = workflowProcessInstanceService.findTask(project.getWorkflowId());
					workflowProcessInstanceService.complete(task.getId(), null);
				}
			}else{//不评标流程
				//project.setManageName("");//将项目负责人名称置为空
				if(Integer.valueOf(ProjectStatus.WAIT_SUBMIT.toString())==commitType){//保存操作
                    project.setStatus(Integer.valueOf(ProjectStatus.WAIT_SUBMIT.toString()));//待提交
				}else{//提交
					//清空默认值
					project.setResponseFile("");//清空默认值
					project.setOthereRequire("");//清空默认值

					//流程 完成任务
					Task task = workflowProcessInstanceService.findTask(project.getWorkflowId());
					workflowProcessInstanceService.complete(task.getId(), null);
				}
			}
			
			
			
			// 项目关联清单附件信息
			String budgetMenuStr[] = budgetMenuData.split(",");
			Resources res = null;
			for(String budgetMenuId : budgetMenuStr){
				res = FileResUtil.getResources(budgetMenuId);
				if(res != null){
					res.setBusinessId(project.getId());
					this.saveOrUpdate(res);
				}
			}
			
			
			//============留痕记录
			if(Integer.valueOf(ProjectStatus.WAIT_SUBMIT.toString())==commitType){//保存操作
				LogUtil.addLog(new LogInfo("添加" + project.getName() + "项目,状态为未提交", user.getId(), user.getName(), String.valueOf(LogType.ADD.ordinal()), project.getClass().getSimpleName(), project
						.getId()));
			}else{//提交
				LogUtil.addLog(new LogInfo("添加" + project.getName() + "项目,状态为待审核", user.getId(), user.getName(), String.valueOf(LogType.ADD.ordinal()), project.getClass().getSimpleName(), project
						.getId()));
			}
		}
		//===================================
		else {// 修改
			ProjectInfo persisted = this.get(ProjectInfo.class, project.getId());
			persisted.setName(project.getName());
			persisted.setBudgetAmount(project.getBudgetAmount());
			persisted.setAgentName(project.getAgentName());
			persisted.setBuyName(project.getBuyName());
			persisted.setAddress(project.getAddress());
			persisted.setOperater(project.getOperater());
			persisted.setContactTel(project.getContactTel());
			persisted.setQq(project.getQq());
			persisted.setCatagoryId(project.getCatagoryId());
			persisted.setFundFrom(project.getFundFrom());
			persisted.setPayType(project.getPayType());
			persisted.setBuyContent(project.getBuyContent());
			//persisted.setAuditable(project.getAuditable());
			persisted.setBuyTel(project.getBuyTel());
			persisted.setTradeType(project.getTradeType());//交易方式
			persisted.setManageLeader(project.getManageLeader());//分管领导
			persisted.setManageName(project.getManageName());
			persisted.setOrganizationCode(project.getOrganizationCode());
			persisted.setPhoneNumber(project.getPhoneNumber());
			ProjectType catagory = this.get(ProjectType.class, project.getCatagoryId());
			if(catagory!=null){
				persisted.setCatagoryName(this.get(ProjectType.class, project.getCatagoryId()).getName());//项目类型
			}
			
			if(Integer.valueOf(ProjectStatus.WAIT_SUBMIT.toString())==commitType){//保存操作
				persisted.setStatus(Integer.valueOf(ProjectStatus.WAIT_SUBMIT.toString()));//待提交
			}else{//提交
				persisted.setStatus(Integer.valueOf(ProjectStatus.WAIT_AUDIT.toString()));//待审核
				if(!persisted.getAuditable()){//不评标流程
					//清空默认值
					persisted.setResponseFile("");//清空默认值
					persisted.setOthereRequire("");//清空默认值
				}
				//流程 完成任务
				Task task = workflowProcessInstanceService.findTask(persisted.getWorkflowId());
				workflowProcessInstanceService.complete(task.getId(), null);
			}
			this.saveOrUpdate(persisted);
			
			//项目关联清单附件信息 
			if(!StringUtil.isEmpty(budgetMenuData)){
				String budgetMenuStr[] = budgetMenuData.split(",");
				List<String> budgetMenuList = new ArrayList<String>(budgetMenuStr.length);
				Collections.addAll(budgetMenuList, budgetMenuStr);
				// 先得到之前关联的清单数据
				List<Resources> resList = FileResUtil.findResources(persisted.getId());
				Iterator<Resources> resIt = resList.iterator();
				Resources res = null;
				while(resIt.hasNext()){
					res = resIt.next();
					if(!budgetMenuList.contains(res.getId())){
						this.remove(res);
					}
				}
				InitCacheData.getInstance().initFileData();
				for(String budgetMenuId : budgetMenuStr){
					res = FileResUtil.getResources(budgetMenuId);
					if(res != null && res.getBusinessId() == null){
						res.setBusinessId(project.getId());
						this.saveOrUpdate(res);
					}
				}
				LogUtil.addLog(new LogInfo("修改" + project.getName() + "项目附件数据", user.getId(), user.getName(), String.valueOf(LogType.UPDATE.ordinal()), persisted.getClass().getSimpleName(),
						persisted.getId()));
			}
			
			
			//============留痕记录
			if(Integer.valueOf(ProjectStatus.WAIT_SUBMIT.toString())==commitType){//保存操作
				LogUtil.addLog(new LogInfo("修改" + project.getName() + "项目数据,状态为未提交", user.getId(), user.getName(), String.valueOf(LogType.UPDATE.ordinal()), persisted.getClass()
						.getSimpleName(), persisted.getId()));
			}else{//提交
				LogUtil.addLog(new LogInfo("修改" + project.getName() + "项目,状态为待审核", user.getId(), user.getName(), String.valueOf(LogType.ADD.ordinal()), project.getClass().getSimpleName(), project
						.getId()));
			}
		} 
	}

	
	@Override
	public List<ProjectInfo> findAllByIds(String ids, ProjectInfo project,
			Page page, Sort sort, Date startTime,
			Date stopTime, Date bidStartTime,
			Date bidStopTime, Double startMoney, Double endMoney) {
		return projectInfoDaoImpl.findAllByIds(ids, project, page, sort, startTime, stopTime, bidStartTime, bidStopTime, startMoney, endMoney);
	}


	@Override
	public int getProjectBidderByProjId(String projId,boolean isEvalution) {
		return this.projectInfoDaoImpl.getProjectBidderByProjId(projId,isEvalution);
	}


	@Override
	public String saveTendeeByProjId(String projectId) {//根据proj_id，系统自动 进行评选中标用户保存到entity表中，并返回中标用户id（根据最低价中标，时间优先原则) 
		List<ProjectBidInfo> list=this.projectInfoDaoImpl.findProjectBidList(projectId);
		Double min=Double.MAX_VALUE;
		ProjectBidInfo winner=null;
		for (ProjectBidInfo pb : list) {
			if(pb.getBidAmount()-(pb.getDiscountAmount()==null?0:pb.getDiscountAmount())<min){
				min=pb.getBidAmount()-(pb.getDiscountAmount()==null?0:pb.getDiscountAmount());
				winner=pb;
			}
		}
		//保存中标用户
		ProjectInfo project = this.get(ProjectInfo.class, projectId);
		project.setWinningId(winner.getUserId());
		project.setWinningName(winner.getBidderName());
		project.setHitMoney(Double.parseDouble(String.valueOf(winner.getBidAmount())));//中标金额
		return winner.getUserId();
	}
	
	@Override
	public ProjectBidInfo getTendeeByProjId(String projectId) {//根据proj_id，系统自动 进行评选中标用户保存到entity表中，并返回中标用户id（根据最低价中标，时间优先原则) 
		List<ProjectBidInfo> list=this.projectInfoDaoImpl.findProjectBidList(projectId);
		Double min=Double.MAX_VALUE;
		ProjectBidInfo winner=null;
		if(!list.isEmpty()){
		for (ProjectBidInfo pb : list) {
			if(pb.getBidAmount()-(pb.getDiscountAmount()==null?0:pb.getDiscountAmount())<min){
				min=pb.getBidAmount()-(pb.getDiscountAmount()==null?0:pb.getDiscountAmount());
				winner=pb;
			}
		}
		//保存中标用户
		ProjectInfo project = this.get(ProjectInfo.class, projectId);
		project.setWinningId(winner.getUserId());
		project.setWinningName(winner.getBidderName());
		project.setHitMoney(Double.parseDouble(String.valueOf(winner.getBidAmount())));//中标金额
		return winner;
		}
		return null;
	}


	@Override
	public List<ProjectInfo> findBiddList(ProjectInfo project, Page page, Sort sort,
			java.sql.Date startTime, java.sql.Date stopTime,
			java.sql.Date bidStartTime, java.sql.Date bidStopTime) {
		return projectInfoDaoImpl.findBiddList(project, page, sort, startTime, stopTime, bidStartTime, bidStopTime);
	}


	@Override
	public ProjectBidInfo getProjectBidderByProjIdAndBidderId(String projectId,
			String bidderId) {
		return projectInfoDaoImpl.getProjectBidderByProjIdAndBidderId(projectId,bidderId);
	}


	@Override
	public List<ProjectInfo> findProjectBiddList(ProjectInfo project, Page page, Sort sort,
			java.sql.Date startTime, java.sql.Date stopTime,
			java.sql.Date bidTime, java.sql.Date bidStopTime) {
		return projectInfoDaoImpl.findProjectBiddList(project, page, sort, startTime, stopTime, bidTime, bidStopTime);
	}


	@Override
	public List<ProjectBidInfo> findProjectBidListByProjectId(Page page,ProjectBidInfo bidInfo) {
		return  projectInfoDaoImpl.findProjectBidListByProjectId(page,bidInfo);
	}
	
	@Override
	public String generateProjectCode(ProjectInfo project) {
		String code="";
		if(project.getAuditable()){
			code = generateCodeByWhere(project);
		}else{
			code = generateCodeByWhere_nobid(project);
		}
		
		return code;
	}


	/**
	 * 生成编号
	 * @param project
	 * @return
	 */
	private String generateCodeByWhere(ProjectInfo project) {
		// 查询区域简称
		User user=this.get(User.class, project.getCreateId());
		Dept dept = (Dept) InitCacheData.getInstance().getCacheData(CacheType.DEPT).get(user.getDeptId());
		Dept unit = (Dept) InitCacheData.getInstance().getCacheData(CacheType.DEPT).get(dept.getpUnit());
		StringBuilder code = new StringBuilder();
		Calendar cal = Calendar.getInstance();
		code.append(cal.get(Calendar.YEAR));//年份
		String deptCode="";
		if(unit.getDeptCode()==null){//当用户为包河区时，无上级部门
			deptCode=dept.getDeptCode().toUpperCase();
		}else{
			deptCode=unit.getDeptCode().toUpperCase();
		}
		code.append(deptCode);//区域
		//项目类型
		ProjectType ProjectType = this.get(ProjectType.class, project.getCatagoryId());
		code.append(ProjectType.getTypeCode().toUpperCase());
		//交易方式
		code.append(project.getTradeType().toUpperCase());
		//序列号(四位数)
		ProjectMaxCount maxCount = (ProjectMaxCount) this.projectInfoDaoImpl//
				.queryMaxCountOfSameArea(cal.get(Calendar.YEAR),dept.getpUnit(),ProjectType.getTypeCode(),project.getTradeType());
		if (maxCount == null) {// 如果不存在则新增一条记录
			maxCount = new ProjectMaxCount();
			maxCount.setUnitId(dept.getpUnit());
			maxCount.setMaxCount(new Long(1));
			maxCount.setCodeType(0);
			maxCount.setYears(cal.get(Calendar.YEAR));//年份
			maxCount.setProjectType(ProjectType.getTypeCode());//项目类型
			maxCount.setTradeType(project.getTradeType());//交易方式
			this.save(maxCount);
			LogUtil.addLog(new LogInfo("添加项目ProjectMaxCount", user.getId(), user.getName(), String.valueOf(LogType.ADD.ordinal()), maxCount.getClass().getSimpleName(), maxCount.getId()));
		} else {// 修改最大数加1			
			maxCount.setMaxCount(maxCount.getMaxCount() + 1);
			LogUtil.addLog(new LogInfo("更新项目ProjectMaxCount", user.getId(), user.getName(), String.valueOf(LogType.ADD.ordinal()), maxCount.getClass().getSimpleName(), maxCount.getId()));
		}
		String orderNo = this.genOrderCode(maxCount.getMaxCount());
		code.append(orderNo);
		//判读是否已存在此编号
		boolean obj = validateUniqueDao.unique("t_proj_info", "code", code.toString(), null);
		if(!obj){//存在,重新生成
			return generateCodeByWhere(project);
		}
		return code.toString();
	}
	
	/**
	 * @description 生成顺序码
	 * @author xuyefei
	 * @date 2016-4-12 上午09:48:57
	 * @return String
	 */
	private String genOrderCode(Long maxCount) {
		// 判断是几位数
		int countLength = maxCount.toString().length();
		if (countLength == 4) {
			return maxCount.toString();
		} else {
			int zeros = (4 - countLength);
			StringBuilder resultCode = new StringBuilder();
			for (int i = 0; i < zeros; i++) {
				resultCode.append("0");
			}
			resultCode.append(maxCount.toString());
			return resultCode.toString();
		}
	}

	public ProjectInfo getProjectByProcessId(String processId) {
		return	projectInfoDaoImpl.findSingleByProcessId(processId);
	}


	@Override
	public boolean isBidByProjIdAndBidderId(String projectId, String bidderId) {
		ProjectBidInfo bidInfo = this.projectInfoDaoImpl.isBidByProjIdAndBidderId(projectId, bidderId);
		return bidInfo!=null?true:false;
	}


	@Override
	public List<ProjectInfo> findAllByStatus(Page page, ProjectInfo pj, String status) {
		return this.projectInfoDaoImpl.findAllByStatus(page,pj,status);
	}


	@Override
	public List<ProjectBidInfo> getProjectBiddersByProjId(String id) {
		return this.projectInfoDaoImpl.getProjectBiddersByProjId(id);
	}
	
	
	/**
	 * 生成编号
	 * @param project
	 * @return
	 */
	private String generateCodeByWhere_nobid(ProjectInfo project) {
		// 查询区域简称
		User user=this.get(User.class, project.getCreateId());
		Dept dept = (Dept) InitCacheData.getInstance().getCacheData(CacheType.DEPT).get(user.getDeptId());
		Dept unit = (Dept) InitCacheData.getInstance().getCacheData(CacheType.DEPT).get(dept.getpUnit());
		StringBuilder code = new StringBuilder();
		Calendar cal = Calendar.getInstance();
		code.append(cal.get(Calendar.YEAR));//年份
		String deptCode="";
		if(unit.getDeptCode()==null){//当用户为包河区时，无上级部门
			deptCode=dept.getDeptCode().toUpperCase();
		}else{
			deptCode=unit.getDeptCode().toUpperCase();
		}
		code.append(deptCode);//区域
		//项目类型
		ProjectType ProjectType = this.get(ProjectType.class, project.getCatagoryId());
		code.append(ProjectType.getTypeCode().toUpperCase());
		//交易方式
		code.append(project.getTradeType().toUpperCase());
		//序列号(四位数)
		ProjectMaxCount maxCount = (ProjectMaxCount) this.projectInfoDaoImpl//
				.queryMaxCountOfSameArea(cal.get(Calendar.YEAR),dept.getpUnit(),ProjectType.getTypeCode(),project.getTradeType());
		if (maxCount == null) {// 如果不存在则新增一条记录
			maxCount = new ProjectMaxCount();
			maxCount.setUnitId(dept.getpUnit());
//			maxCount.setMaxCount(new Long(8001));
			maxCount.setMaxCount_nobid(new Long(8001));
			maxCount.setCodeType(0);
			maxCount.setYears(cal.get(Calendar.YEAR));//年份
			maxCount.setProjectType(ProjectType.getTypeCode());//项目类型
			maxCount.setTradeType(project.getTradeType());//交易方式
			this.save(maxCount);
			LogUtil.addLog(new LogInfo("添加项目ProjectMaxCount_nobid", user.getId(), user.getName(), String.valueOf(LogType.ADD.ordinal()), maxCount.getClass().getSimpleName(), maxCount.getId()));
		} else {// 修改最大数加1
			if(maxCount.getMaxCount_nobid()==null || maxCount.getMaxCount_nobid()<8001){
				maxCount.setMaxCount_nobid(new Long(8001));
			}else{
				maxCount.setMaxCount_nobid(maxCount.getMaxCount_nobid() + 1);
			}
			
			LogUtil.addLog(new LogInfo("更新项目ProjectMaxCount_nobid", user.getId(), user.getName(), String.valueOf(LogType.ADD.ordinal()), maxCount.getClass().getSimpleName(), maxCount.getId()));
		}
		String orderNo = this.genOrderCode(maxCount.getMaxCount_nobid());
		code.append(orderNo);
		//判读是否已存在此编号
		boolean obj = validateUniqueDao.unique("t_proj_info", "code", code.toString(), null);
		if(!obj){//存在,重新生成
			return generateCodeByWhere_nobid(project);
		}
		return code.toString();
	}
	

}
